home *** CD-ROM | disk | FTP | other *** search
- ; ATTR.ASM -- File Attribute Utility
- ; ==================================
-
- CSEG Segment
- Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
- Org 0080h
- Parameter Label Byte ; Parameter is here
- Org 0100h
- Entry: Jmp Begin ; Entry Point
-
- ; Most Data (some more at end of program)
- ; ---------------------------------------
-
- db "ATTR (C) 1986, Ziff-Davis Publishing Co.",1Ah
- db " Programmed by Charles Petzold ",1Ah
- SyntaxMsg db "Syntax: ATTR [+A|-A] [+S|-S] [+H|-H] [+R|-R] "
- db "[drive:][path]filename",13,10
- db " Archive System Hidden Read-Only$"
- DosVersMsg db "ATTR: Needs DOS 2.0 +$"
- FlagErrMsg db "ATTR: Incorrect flag$"
- FileSpecMsg db "ATTR: Incorrect File Spec$"
- Delimiters db 9,' ,;=',13
- FlagList db "ASHR", 20h, 04h, 02h, 01h
- AllFlagList db " $Arc $Dir $$$$$$Sys $Hid $R-O$"
- ChangeFlag db 0
- AndAttrBits db 0
- OrAttrBits db 0
- SearchString dw ?
- AppendFileName dw ?
-
- ; Check DOS Version
- ; -----------------
-
- Begin: Mov AH, 30h ; Check for DOS Version
- Int 21h ; through DOS call
- Cmp AL, 2 ; See if it's 2.0 or above
- Jae DosVersOK ; If so, continue
-
- Mov DX, Offset DosVersMsg ; Error message
- ErrorExit: Mov AH, 9 ; Print String function call
- Int 21h ; Do it
- Int 20h ; And exit prematurely
-
- ; Parse Command Line to get file specification
- ; --------------------------------------------
-
- DosVersOK: Mov SI, 1+Offset Parameter ; Parameter string pointer
- Cld ; Directions forward
-
- FlagSearch: Lodsb ; Get Byte
- Mov DI, Offset Delimiters ; Check if delimiter
- Mov CX, 5 ; Five delimiters to check
- Repne Scasb ; Scan the string
- Je FlagSearch ; If delimiter, circle back
- Mov DX, Offset SyntaxMsg ; Possible error msg
- Cmp AL, 13 ; If carriage return, no file
- Je ErrorExit ; so exit with message
-
- Mov DI, Offset OrAttrBits ; Pointer to plus flag saver
- Cmp AL, '+' ; See if plus sign
- Je PlusOrMinus ; If so, save the bit
- Mov DI, Offset AndAttrBits ; Pointer to minus flag saver
- Cmp AL, '-' ; See if minus sign
- Jne MustBeFile ; If not, it must be file name
-
- PlusOrMinus: Mov [ChangeFlag],-1 ; Set for changing
- Lodsb ; Get the next byte
- And AL, 0DFh ; Capitalize it
- Mov BX, Offset FlagList ; List for scanning
- Mov CX, 4 ; Scan for A, S, H, and R
-
- SearchList: Cmp AL, [BX] ; See if a match
- Jz FoundFlag ; If so, proceed to save
- Inc BX ; Kick up pointer
- Loop SearchList ; And loop around for next
- Mov DX, Offset FlagErrMsg ; Otherwise, set message
- Jmp ErrorExit ; And terminate
-
- FoundFlag: Mov AL, [BX + 4] ; Get bit mask
- Or [DI], AL ; Turn saved bit on
- Jmp FlagSearch ; And continue looking
-
- MustBeFile: Not [AndAttrBits] ; Invert bits for turn off
- Mov [SearchString], SI ; Save file name pointer
- Dec [SearchString] ; Actually one byte lower
-
- EndSearch: Lodsb ; Get Byte
- Mov DI, Offset Delimiters ; Check if delimiter
- Mov CX, 6 ; Six delimiters including CR
- Repne Scasb ; Scan the string
- Jne EndSearch ; If not delimiter, keep going
-
- ; Transfer Search String down at end of program
- ; ---------------------------------------------
-
- Dec SI ; Points after file spec
- Mov Byte Ptr [SI], 0 ; Make it ASCIIZ string
- Mov CX, SI ; CX points to end
- Mov SI, [SearchString] ; SI points to beginning
- Sub CX, SI ; Now CX is length of it
- Mov DI, Offset PathAndFile ; Destination of string
- Mov [AppendFileName], DI ; Save it here also
-
- SearchTrans: Lodsb ; Get byte of search string
- Stosb ; And save it down below
- Cmp AL, ':' ; See if drive marker
- Je PossibleEnd ; If so, take note of it
- Cmp AL, '\' ; See if path separator
- Jne NextCharacter ; If not, skip next code
-
- PossibleEnd: Mov [AppendFileName], DI ; This is the new end
- NextCharacter: Loop SearchTrans ; Do it again until done
-
- ; Find Files from Search String
- ; -----------------------------
-
- Mov DX, Offset DTABuffer ; Set File Find buffer
- Mov AH, 1Ah ; by calling DOS
- Int 21h
-
- Mov DX, [SearchString] ; Search string
- Mov CX, 16h ; Search Everything
- Mov AH, 4Eh ; Find first file
-
- FindFile: Int 21h ; Call DOS to find file
- Jnc Continue ; If no error continue
- Cmp AX, 18 ; If not "no more files" error
- Jnz FindError ; print error message
- Jmp NoMoreFiles ; Now get out of the loop
-
- FindError: Mov DX, Offset FileSpecMsg ; Error message for file spec
- Jmp ErrorExit ; Exit and print message
-
- Continue: Mov SI, 30+Offset DTABuffer ; Points to filename
- Cmp Byte Ptr [SI], '.' ; See if "dot" entry
- Jnz FileIsOK ; If not, continue
- Jmp FindNextFile ; If so, skip it
-
- FileIsOK: Mov DI, [AppendFileName] ; Destination of file name
- Mov CX, 14 ; Number of bytes to display
-
- TransferName: Lodsb ; Get the byte in file name
- Stosb ; Save it
- Or AL, AL ; See if terminating zero
- Jz PadWithBlanks ; If so, display blanks
- Call DisplayChar ; Display the character
- Loop TransferName ; And loop back around
-
- PadWithBlanks: Mov AL, ' ' ; Pad names with blanks
- Call DisplayChar
- Loop PadWithBlanks ; And loop until CX is zero
-
- ; Change And Display File Attributes
- ; ----------------------------------
-
- Mov DX, Offset PathAndFile ; Points to ASCIIZ string
- Test [ChangeFlag], -1 ; See if changing attributes
- Jz DisplayIt ; If not, just display them
-
- Mov AX, 4300h ; Get file attribute
- Int 21h ; by calling DOS
- And CL, 27h ; Zero out some bits
- And CL, [AndAttrBits] ; Turn off some bits
- Or CL, [OrAttrBits] ; Turn on some bits
- Mov AX, 4301h ; Set file attribute
- Int 21h ; by calling DOS
-
- DisplayIt: Mov AX, 4300h ; Get file attribute
- Int 21h ; by calling DOS
- Mov BL, CL ; BL is attributes
- Or BL, 08h ; Turn on Volume bit
- Shl BL, 1 ; Shift to get rid of
- Shl BL, 1 ; unused bits
- Mov CX, 6 ; Number of bits left
- Mov DX, 5+Offset AllFlagList; Storage of abbreviations
-
- AttrListLoop: Push DX ; Save abbreviation pointer
- Shl BL, 1 ; Shift bit into carry
- Jc FlagIsOn ; See if it's on
- Mov DX, Offset AllFlagList ; If not, print blanks
-
- FlagIsOn: Mov AH, 9 ; Print string
- Int 21h ; by calling DOS
- Pop DX ; Get back abbreviation ptr
- Add DX, 5 ; Kick up for next bit
- Loop AttrListLoop ; And loop around
- Mov AL, 13 ; Print carriage return
- Call DisplayChar
- Mov AL, 10 ; Print line feed
- Call DisplayChar
-
- FindNextFile: Mov AH, 4Fh ; Find next file
- Jmp FindFile ; By looping around
-
- NoMoreFiles: Int 20h ; Terminate
-
- ; SUBROUTINE: Display Character in AL
- ; -----------------------------------
-
- DisplayChar: Push AX
- Push DX
- Mov DL, AL ; Move character to DL
- Mov AH, 2 ; Display it
- Int 21h ; by calling DOS
- Pop DX
- Pop AX
- Ret
-
- ; Some data stored at end to cut down COM size
- ; --------------------------------------------
-
- DTABuffer Label Byte ; For file find calls
- PathAndFile equ DTABuffer + 43 ; For file path and name
- CSEG EndS ; End of the segment
- End Entry ; Denotes entry point